package models

// @Title       用户分析
// @author      liqi 2018/12/18 15:50
// @Description 用户统计分析

import (
	"context"
	"fmt"
	"go_backend/helper"
	"io"
	"strconv"
	"time"

	"github.com/astaxie/beego/orm"
	"gopkg.in/olivere/elastic.v6" //这里使用的是版本5，最新的是6，有改动
)

func init() {
	// 注册模型
	orm.RegisterModel(new(YyStatUser))

	// 连接 elasticsearch
	serverRegister()
}

// 测试
type Datas struct {
	Id        int       `json:"id"`
	Sex       int       `json:"sex"`
	Nickname  string    `json:"nickname"`
	CreatedAt time.Time `json:"created_at"`
}

// 活跃用户
type Logs struct {
	UserId    int       `json:"user_id"`
	Sex       int       `json:"sex"`
	Type      int       `json:"type"`
	CreatedAt time.Time `json:"created_at"`
}

// 用户分析表yy_stat_user
type YyStatUser struct {
	Id               int    `orm="auto;pk"`
	New_user_boy     int    //男
	New_user_girl    int    //女
	Active_user_boy  int    //活跃男
	Active_user_girl int    //活跃女
	Platform         int    //1:十音 2:cps
	Stat_date        string //统计日期
}

// @Title   AnalyzeUsers
// @author  liqi 2018/12/13 14:05
// @param	userType int  1：十音 2：cps
// @param	goerr	int	错误信号	1：错误或异常 0：正常退出
// @Description 查询当日新增人数 / 活跃人数

var (
	err    error
	esLog  = "login_log" // 登录日志表（活跃用户）
	estype = "info"
)

func AnalyzeUsers(userType int, goerr chan int) {
	var esuser = "user" // 总后台用户表（十音 新增用户）
	if userType == 2 {
		esuser = "cps_user" // cps用户表（cps 新增用户）
	}
	var udata YyStatUser                                              // 组装数据
	udata.Platform = userType                                         // 十音:1  || cps:2
	udata.Stat_date = getStatTime()                                   // 统计时间
	udata.New_user_boy, err = getAddUser(esuser, getQC(userType, 1))  // 新增注册男
	udata.New_user_girl, err = getAddUser(esuser, getQC(userType, 2)) // 新增注册女
	udata.Active_user_boy = getActiveUser(userType, 1)                // 活跃用户男
	udata.Active_user_girl = getActiveUser(userType, 2)               // 活跃用户女
	//fmt.Println(userType, "、boy：", udata.New_user_boy, "girl：", udata.New_user_girl, "activeBoy：", udata.Active_user_boy, "activeGirl：", udata.Active_user_girl)
	// 错误退出
	if err != nil {
		goerr <- 1
		return
	}
	// 插入数据
	insertRecord(udata, goerr)
}

// @Title	getAddUser
// @author  liqi 2018/12/15 18:08
// @Description 新增注册用户统计

func getAddUser(index string, boolQ *elastic.BoolQuery) (int, error) {
	result, err := client.Search(index).Type(estype).Sort("created_at", false).Size(0).Query(boolQ).Do(ctx)
	return int(result.Hits.TotalHits), err
}

// @Title       getActiveUser
// @author      liqi 2018/12/15 18:09
// @Description 活跃用户统计

func getActiveUser(userType int, sex int) int {
	// 开始时间，结束时间
	starttime, endtime := getStartEndTime()
	url := "http://127.0.0.1:9200/" + esLog + "/" + estype + "/_search"
	activeCount := helper.EsUserGroup(userType, sex, starttime, endtime, url)
	return activeCount
}

// @Title   getBoolQ
// @author  liqi 2018/12/14 18:06
// @param userType int 1:十音 2:cps
// @param sex int 1:男 2:女
// @Description 获取查询条件
func getQC(userType int, sex int) *elastic.BoolQuery {

	// 开始时间，结束时间
	starttime, endtime := getStartEndTime()
	//通用查询条件
	normalQ := elastic.NewBoolQuery()
	normalQ.Must(elastic.NewRangeQuery("created_at").Gte(starttime).Lt(endtime)) // 时间区间
	normalQ.Must(elastic.NewMatchQuery("sex", sex))

	// 活跃用户统计（弃用）
	// !!没有找到groupBy的方法，改用原生语句查询!!
	activeQ := elastic.NewBoolQuery()
	activeQ.Must(elastic.NewRangeQuery("created_at").Gte(starttime).Lt(endtime)) // 时间区间
	activeQ.Must(elastic.NewMatchQuery("sex", sex))
	activeQ.Must(elastic.NewQueryStringQuery("type:" + strconv.Itoa(userType))) // 1:十音 2:cps

	return normalQ
}

// @Title   insertRecord
// @author  liqi 2018/12/13 20:29
// @Description  插入数据库

func insertRecord(insertData YyStatUser, goerr chan int) {
	o := orm.NewOrm()
	id, err := o.Insert(&insertData)
	fmt.Println("id:::", id)
	if err == nil {
		goerr <- 0
		return
	}
	goerr <- 1
}

// @Title   getStartEndTime
// @author  liqi 2018/12/13 11:37
// @Description	获取查询开始日期，结束日期

func getStartEndTime() (string, string) {
	//starttime := time.Now().AddDate(0, 0, -1).Format("2006-01-02T00:00:00+08:00")
	//endtime := time.Now().Format("2006-01-02T00:00:00+08:00")
	starttime := "2017-01-27T00:00:00+08:00"
	endtime := "2017-01-28T00:00:00+08:00"
	return starttime, endtime
}

// @Title   getStatTime
// @author  liqi 2018/12/13 11:37
// @Description	获取统计日期

func getStatTime() string {
	//datetime := time.Now().AddDate(0, 0, -1).Format("2006-01-02")
	datetime := "2017-01-27"
	return datetime
}

// @Title	allDatas
// @author  liqi 2018/12/13 14:40
// @Description	使用协程，游标取全部数据（暂时搁置）

func allDatas(num int) error {
	esindex, estype := "book", "user" // 测试
	scroll := client.Scroll(esindex).Type(estype).Size(num)
	//for {
	results, err := scroll.Do(context.Background())
	if err == io.EOF {
		return nil // all results retrieved
	}
	if err != nil {
		return err // something went wrong
	}

	// Send the hits to the hits channel
	for _, hit := range results.Hits.Hits {
		//hits <- *hit.Source
		fmt.Println(*hit.Source)
	}
	//}
	return nil
}
